﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Transactions;
using HengTong.Model;
using HengTong.Model.Db;
using WalkingTec.Mvvm.Core;
using HengTong.Model.Db.Hr;
using HengTong.Model.Db.Hr.Bill;
using Microsoft.Extensions.DependencyInjection;
using HengTong.Model.Services;
using Microsoft.EntityFrameworkCore;
using TiaoTaoHelper.Models;
using TiaoTaoHelper.Wtm.Interfaces;
using TiaoTaoHelper.Wtm.Models;
using UUIDNext;
using WalkingTec.Mvvm.Core.Support.Json;


namespace HengTong.ViewModel.Hr.SysHrInterviewRequestBillVms
{
    public partial class SysHrInterviewRequestBillVm : CrudVm<SysHrInterviewRequestBill>
    {
        public SysHrInterviewRequestBillVm()
        {
            SetInclude(x => x.Org);
            SetInclude(x => x.Group);
            SetInclude(x => x.JobPosition);
            SetInclude(x => x.PersonEducations);
            SetInclude(x => x.PersonFamilies);
            SetInclude(x => x.PersonWorks);
            SetInclude(x => x.PersonTrainExams);
            SetInclude(x => x.PersonMedicals);
            SetInclude(x => x.PersonResumes);
            SetInclude(x => x.PersonContracts);
        }

        protected override void InitVM()
        {
            base.InitVM();
        }

        public override async Task DoAddAsync()
        {
            // 判断是否已经申请过同一个招聘发布单ID
            if (Entity.RecruitPublishRequestBillId.HasValue)
            {
                var existingApplication = await DC.Set<SysHrInterviewRequestBill>()
                    .AsNoTracking()
                    .FirstOrDefaultAsync(e =>
                        e.RecruitPublishRequestBillId == Entity.RecruitPublishRequestBillId.Value &&
                        e.CreateBy == Wtm.LoginUserInfo.ITCode);
                if (existingApplication != null)
                {
                    MSD.AddModelError(" ", "您已申请过该招聘发布单，请勿重复申请.");
                    return;
                }
            }

            // 公司，部门，岗位等信息自动带出，部门为培训中心，岗位为培训中心职员
            if (Entity.RecruitPublishRequestBillId.HasValue)
            {
                var recruitPublishRequestBill = await DC.Set<SysHrRecruitPublishRequestBill>()
                    .Include(r => r.JobPosition)
                    .AsNoTracking()
                    .FirstOrDefaultAsync(r => r.ID == Entity.RecruitPublishRequestBillId.Value);

                if (recruitPublishRequestBill == null || !recruitPublishRequestBill.IsExternalPublish.HasValue ||
                    !recruitPublishRequestBill.IsExternalPublish.Value)
                {
                    MSD.AddModelError(" ", " 关联的招聘发布单未发布，无法提交应聘申请");
                    return;
                }

                // 从招聘发布单中获取组织信息
                Entity.OrgId = recruitPublishRequestBill.OrgId;

                // 查找培训中心部门
                var trainingGroup = await DC.Set<SysGroup>()
                    .FirstOrDefaultAsync(g => g.GroupName.Contains("培训中心"));
                if (trainingGroup != null)
                {
                    Entity.GroupId = trainingGroup.ID;
                }

                // 查找培训中心职员岗位
                var trainingPosition = await DC.Set<SysJobPosition>()
                    .FirstOrDefaultAsync(p => p.Name.Contains("培训中心职员"));
                if (trainingPosition != null)
                {
                    Entity.JobPositionId = trainingPosition.ID;
                }
            }

            if (Entity is IBill bill)
            {
                Entity.BillStatus = BillStatus.草稿;
                Entity.WorkflowStatus = WorkflowStatus.待提交;
                var result = await GenerateCodeAsync();
                if (result.Code == 200)
                {
                    Entity.BillCode = result.Data;
                }
                else
                {
                    MSD.AddModelError(" ", $"生成编码异常. {result.Message}");
                    return;
                }
            }

            Entity.ID = Uuid.NewDatabaseFriendly(Database.SqlServer);

            if (Entity is IBasePoco poco)
            {
                poco.CreateBy = Wtm.LoginUserInfo?.ITCode;
                poco.UpdateBy = Wtm.LoginUserInfo?.ITCode;
                poco.CreateTime = DateTime.Now;
                poco.UpdateTime = DateTime.Now;
            }

            // 生成并保存 StaffNo
            var staffNo = await GenerateNegativeStaffNoAsync();
            Entity.StaffNo = staffNo; // 派生类属性
            await base.DoAddAsync();
        }

        public override async Task DoEditAsync(bool updateAllFields = false)
        {
            if (Entity is IBill { WorkflowStatus: WorkflowStatus.提交中 })
            {
                // 判断子表家庭成员是否有数据，如果没有不发保存
                var families = await DC.Set<SysPersonFamily>()
                    .Where(f => f.PersonId == Entity.ID)
                    .AsNoTracking()
                    .ToListAsync();
                if (!families.Any())
                {
                    MSD.AddModelError(" ", "请至少添加一条家庭成员信息");
                    return;
                }

                // 判断子表学习经历是否有数据，如果没有不发保存
                var educations = await DC.Set<SysPersonEducation>()
                    .Where(e => e.PersonId == Entity.ID)
                    .AsNoTracking()
                    .ToListAsync();
                if (!educations.Any())
                {
                    MSD.AddModelError(" ", "请至少添加一条学习经历信息");
                    return;
                }

                // 检查是否填写了小学、初中、高中的学习经历
                var hasElementary = educations.Any(e => e.EducationLevel == EducationLevel.小学);
                var hasMiddleSchool = educations.Any(e => e.EducationLevel == EducationLevel.初中);
                var hasHighSchool = educations.Any(e => e.EducationLevel == EducationLevel.高中);
                var hasCollegeOrAbove = educations.Any(e =>
                    e.EducationLevel == EducationLevel.大专 || e.EducationLevel == EducationLevel.本科);


                if (!hasElementary || !hasMiddleSchool || !hasHighSchool || !hasCollegeOrAbove)
                {
                    var missingLevels = new List<string>();
                    if (!hasElementary) missingLevels.Add("小学");
                    if (!hasMiddleSchool) missingLevels.Add("初中");
                    if (!hasHighSchool) missingLevels.Add("高中");
                    if (!hasCollegeOrAbove) missingLevels.Add("大专或本科");

                    MSD.AddModelError(" ", $"请完善学习经历信息,缺少:{string.Join("、", missingLevels)}");
                    return;
                }

                var raw = await DC.Set<SysHrInterviewRequestBill>()
                    .AsNoTracking()
                    .FirstOrDefaultAsync(e => e.ID == Entity.ID);
                if (raw.WorkflowStatus != WorkflowStatus.待提交)
                {
                    MSD.AddModelError(" ", "单据已提交审核,请勿重复提交.");
                    return;
                }

                //判断人员是否设定部门，如果没有则设置为培训中心
                if (Wtm.LoginUserInfo?.Groups?.Count == 0)
                {
                    var group = await DC.Set<SysGroup>()
                        .AsNoTracking()
                        .Where(e => e.GroupName.Contains("培训中心"))
                        .FirstOrDefaultAsync();
                    if (group != null)
                    {
                        var d = new FrameworkUserGroup
                        {
                            GroupCode = group.GroupCode,
                            TenantCode = Wtm.LoginUserInfo.CurrentTenant,
                            UserCode = Wtm.LoginUserInfo?.ITCode
                        };
                        await DC.Set<FrameworkUserGroup>().AddAsync(d);
                        await DC.SaveChangesAsync();
                        Wtm.LoginUserInfo?.Groups.Add(new SimpleGroup()
                        {
                            ID = group.ID,
                            GroupCode = group.GroupCode,
                            GroupName = group.GroupName
                        });
                        await Wtm.RemoveUserCache([d.UserCode]);
                    }
                }

                var result = await StartWorkflowAsync("应聘申请流程");
                if (result == null) return;
                if (!result.Executed)
                {
                    MSD.AddModelError(" ", $"提交审核异常. {result.Exception?.Message}");
                    return;
                }

                Entity.BillStatus = BillStatus.正文;
                Entity.WorkflowStatus = WorkflowStatus.审核中;
            }

            if (Entity is IBasePoco poco)
            {
                poco.UpdateBy = Wtm.LoginUserInfo?.ITCode;
                poco.UpdateTime = DateTime.Now;
            }

            // 检查当前实体的StaffNo是否为空
            if (string.IsNullOrEmpty(Entity.StaffNo))
            {
                var originalEntity = await DC.Set<SysHrInterviewRequestBill>()
                    .AsNoTracking()
                    .FirstOrDefaultAsync(e => e.ID == Entity.ID);

                if (originalEntity != null)
                {
                    Entity.StaffNo = originalEntity.StaffNo;
                }
            }

            await base.DoEditAsync(updateAllFields);
        }

        /// <summary>
        /// 必须使用异步事务, 否则工作流引擎会和当前事务冲突
        /// </summary>
        /// <param name="upAllFields"></param>
        public async Task ApproveAsync(bool upAllFields = false)
        {
            using var transactionScope = new TransactionScope(
                TransactionScopeOption.Required,
                new TransactionOptions
                {
                    IsolationLevel = IsolationLevel.ReadCommitted,
                    Timeout = TimeSpan.FromMinutes(10) // 增加超时时间到10分钟
                },
                TransactionScopeAsyncFlowOption.Enabled);
            try
            {
                if (Entity.BillStatus == BillStatus.草稿) Entity.BillStatus = BillStatus.正文;
                Entity.Approver = Wtm.LoginUserInfo?.ITCode;
                Entity.ApprovalTime = DateTime.Now;

                await base.DoEditAsync(upAllFields);
                if (MSD.IsValid)
                {
                    var result = await ContinueWorkflowAsync(ActionName, Remark, "应聘申请流程");
                    if (result.Executed == true)
                    {
                        transactionScope.Complete(); // 提交事务
                    }
                    else
                    {
                        MSD.AddModelError(" ", $"工作流执行失败");
                    }
                }
                // 如果到这里，事务会自动回滚
            }
            catch (Exception e)
            {
                // TransactionScope会自动回滚，无需手动操作
                MSD.AddModelError(" ", $"审批操作异常: {e.Message}");
            }
        }

        /// <summary>
        /// 生成编码
        /// </summary>
        /// <returns></returns>
        public async Task<Result<string>> GenerateCodeAsync()
        {
            if (Entity is IBill bill)
            {
                var scope = Wtm.ServiceProvider.CreateScope();
                var service = scope.ServiceProvider.GetRequiredService<CodeGeneratorService>();
                var code = await service.GenerateCodeAsync(Entity.GetType().Name);
                return new Result<string>()
                {
                    Data = code
                };
            }

            return new Result<string>("实体未实现IBill接口");
        }

        /// <summary>
        /// 预测编码
        /// </summary>
        /// <returns></returns>
        public async Task<Result<string>> PredictCodeAsync()
        {
            if (Entity is IBill bill)
            {
                var scope = Wtm.ServiceProvider.CreateScope();
                var service = scope.ServiceProvider.GetRequiredService<CodeGeneratorService>();
                var code = await service.PreviewNextCodeAsync(Entity.GetType().Name);
                return new Result<string>()
                {
                    Data = code
                };
            }

            return new Result<string>("实体未实现IBill接口");
        }

        public override void DoDelete()
        {
            base.DoDelete();
        }

        /// <summary>
        /// 生成应聘申请的负数工号，从-1000开始递减
        /// </summary>
        /// <returns></returns>
        private async Task<string> GenerateNegativeStaffNoAsync()
        {
            using var transaction = await DC.Database.BeginTransactionAsync();
            try
            {
                const int startingNumber = -1000;

                // 查询所有负数工号，范围在-1000以下
                var existingNegativeStaffNos = await DC.Set<SysHrInterviewRequestBill>()
                    .Where(x => x.StaffNo != null && x.StaffNo.StartsWith("-"))
                    .Select(x => x.StaffNo)
                    .AsNoTracking()
                    .ToListAsync();

                // 解析出所有有效的负数工号
                var existingNumbers = existingNegativeStaffNos
                    .Where(staffNo => int.TryParse(staffNo, out var num) && num <= startingNumber)
                    .Select(int.Parse)
                    .ToList();

                int newStaffNo;
                if (!existingNumbers.Any())
                {
                    // 如果没有任何负数工号，从-1000开始
                    newStaffNo = startingNumber;
                }
                else
                {
                    // 找到最小值（最负的数），然后递减1
                    var minNumber = existingNumbers.Min();
                    newStaffNo = minNumber - 1;
                }

                var staffNoString = newStaffNo.ToString();

                // 双重检查：确保生成的工号不存在
                var exists = await DC.Set<SysHrInterviewRequestBill>()
                    .AnyAsync(x => x.StaffNo == staffNoString);

                if (exists)
                {
                    // 如果存在冲突，递归重试
                    await transaction.RollbackAsync();
                    return await GenerateNegativeStaffNoAsync();
                }

                await transaction.CommitAsync();
                return staffNoString;
            }
            catch
            {
                await transaction.RollbackAsync();
                throw;
            }
        }
    }
}